﻿
namespace LxBasic
{
    public class AssignFaceToCellTool
    {
        private IdLink.Elements _InnOFEles;
        private IdLink.Elements _InnNFEles;
        private IdLink.Elements _BouFEles;
        private LinkCell[] _InnCells;
        public AssignFaceToCellTool(int innCellsCount, int innFacesCount, int bCFCount)
        {
            Initialize(innCellsCount, innFacesCount, bCFCount);
        }
        public void Initialize(int innCellsCount, int innFacesCount, int bCFCount)
        {
            _InnOFEles = new IdLink.Elements(innFacesCount);
            _InnNFEles = new IdLink.Elements(innFacesCount);
            _BouFEles = new IdLink.Elements(bCFCount);
            CheckCreator.ArrayEnough(ref _InnCells, innCellsCount);
            Array.Fill(_InnCells, new LinkCell()
            {
                IOFaces = new(_InnOFEles),
                INFaces = new(_InnNFEles),
                BFaces = new(_BouFEles)
            });
        }

        public void AssignInnFaceToCell(int oCell, int nCell, int faceId)
        {
            _InnCells[oCell].IOFaces.Add(faceId);
            _InnCells[nCell].INFaces.Add(faceId);
        }
        public void AssignBouFacesToCell(int tarCell, int bFaceId)
        {
            _InnCells[tarCell].BFaces.Add(bFaceId);
        }
        public (int[] adjFaces, int OFaceEnd, int NFaceEnd) GetFaces(int cellId)
        {
            ref var c = ref _InnCells[cellId];
            int oFaceEnd = c.IOFaces.Count;
            int nFaceEnd = oFaceEnd + c.INFaces.Count;
            var array = new int[nFaceEnd + c.BFaces.Count];
            c.IOFaces.CopyTo(array, 0);
            c.INFaces.CopyTo(array, oFaceEnd);
            c.BFaces.CopyTo(array, nFaceEnd);
            return (array, oFaceEnd, nFaceEnd);
        }
        private struct LinkCell
        {
            public IdLink.List IOFaces;
            public IdLink.List INFaces;
            public IdLink.List BFaces;
        }

#if DEBUG
        public void Test()
        {
            test1();
        }
        private void test1()
        {
            int a = 5, b = 14, c = 13;
            Initialize(a, b, c);
            for (int i1 = 0; i1 < b; i1++)
            {
                AssignInnFaceToCell(i1 % a, i1 % a, i1);

            }
            for (int i1 = 0; i1 < c; i1++)
            {
                AssignBouFacesToCell(i1 % a, i1);
            }
            for (int i1 = 0; i1 < a; i1++)
            {
                var r = GetFaces(i1);
                Console.WriteLine($"Cell ID:{i1}  OEnd:{r.OFaceEnd}  NEnd:{r.NFaceEnd}  adjFaces:{string.Join(',', r.adjFaces)}");
            }
        }
#endif
    }
    public class AssignJointToBoundTool
    {
        private IdLink.Elements _OJoiEles;
        private IdLink.Elements _NJoiEles;
        private IdLink.List[] _OBouF;
        private IdLink.List[] _NBouF;
        public AssignJointToBoundTool(int oBouFCount, int nBouFCount, int jointCount)
        {
            Initialize(oBouFCount, nBouFCount, jointCount);
        }
        public void Initialize(int oBouFCount, int nBouFCount, int jointCount)
        {
            _OJoiEles = new IdLink.Elements(jointCount);
            _NJoiEles = new IdLink.Elements(jointCount);

            CheckCreator.ArrayEnough(ref _OBouF, oBouFCount);
            CheckCreator.ArrayEnough(ref _NBouF, nBouFCount);
            Array.Fill(_OBouF, new IdLink.List(_OJoiEles));
            Array.Fill(_NBouF, new IdLink.List(_NJoiEles));
        }

        public void AssignJointToSide(int oBouFId, int nBouFId, int jointId)
        {
            _OBouF[oBouFId].Add(jointId);
            _NBouF[nBouFId].Add(jointId);
        }

        public int[] GetOBouFJoints(int oBouFId)
        {
            return _OBouF[oBouFId].ToArray();
        }
        public int[] GetNBouFJoints(int nBouFId)
        {
            return _NBouF[nBouFId].ToArray();
        }
    }
}
